#include "uploadvideopage.h"
#include "ui_uploadvideopage.h"
#include "util.h"
#include "vidhub.h"
#include <QFileDialog>
#include "model/datacenter.h"
#include "toast.h"

UploadVideoPage::UploadVideoPage(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::UploadVideoPage)
{
    ui->setupUi(this);

    // imgaeLabel遮盖了QPushButton, 事件会被imageLabel优先捕获
    ui->imageLabel->setAttribute(Qt::WA_TransparentForMouseEvents, true);

    // 获取所有分类，并更新到界⾯
    auto dataCenter = model::DataCenter::getInstance();
    auto kindAndTag = dataCenter->getKindAndTagClassPtr();
    ui->kinds->addItems(kindAndTag->getAllKind());
    ui->kinds->setCurrentIndex(-1); // 默认不选中

    // 默认情况下，上传视频成功图⽚隐藏，视频上传成功后显⽰
    ui->downIcon->hide();

    connect(ui->commitBtn, &QPushButton::clicked, this, &UploadVideoPage::onCommitBtnClicked);
    connect(ui->videoTitle, &QLineEdit::textChanged, this, &UploadVideoPage::onLineEditTextChanged);
    connect(ui->plainTextEdit, &QPlainTextEdit::textChanged, this, &UploadVideoPage::onPlainEditTextChanged);
    connect(ui->changeButton, &QPushButton::clicked, this, &UploadVideoPage::onChangeButtonClicked);
    // 分类选择改变
    connect(ui->kinds, &QComboBox::currentTextChanged, this, &UploadVideoPage::onUpdateTags);
    // 上传视频完成
    connect(dataCenter, &model::DataCenter::uploadVideoDone, this, &UploadVideoPage::onUploadVideoDone);
    // 上传图片完成
    connect(dataCenter, &model::DataCenter::uploadPhotoDone, this, [=](const QString& photoId, QWidget* whichPage){
        if(whichPage != ui->imageLabel){
            return;
        }
        coverImageId = photoId;
        isUploadPhotoOK = true;
    });
    // 上传视频信息成功
    connect(dataCenter, &model::DataCenter::uploadVideoDescDone, this, [=](){
        // 清空本次上传视频时在界面上的数据
        resetPage();
        // 切换回我的页面
        emit switchMySelfWidgetPage(MyselfPage);
    });
}

UploadVideoPage::~UploadVideoPage()
{
    delete ui;
}

void UploadVideoPage::setVideoTittle(const QString &videoPath)
{
    this->videoPath = videoPath;
    // 从文件路径中截取出文件的名称
    // D:/work/abc/111.mp4
    int start = videoPath.lastIndexOf('/')+1;
    QString videoTitle = videoPath.mid(start);
    ui->videoTitle->setText(videoTitle);
    ui->fileName->setText(videoTitle);
}

void UploadVideoPage::onCommitBtnClicked()
{
    if(!isUploadVideoOK){
        Toast::showMessage("等待视频上传完成");
        return;
    }

    if(!isUploadPhotoOK){
        Toast::showMessage("等待视频封面图上传完成");
        return;
    }

    if(!isDurationOK){
        Toast::showMessage("等待视频总时长获取完成");
        return;
    }

    // 将页面中的视频信息上传到服务器
    if(isUploadVideoOK && isUploadPhotoOK && isDurationOK){
        // 构建视频上传信息结构体
        model::VideoDesc videoDesc;
        videoDesc.videoFileId = videoFileId;
        videoDesc.photoFileId = coverImageId;
        videoDesc.videoTitle = ui->videoTitle->text();
        videoDesc.videoDesc = ui->plainTextEdit->toPlainText();
        videoDesc.kind = ui->kinds->currentText();
        videoDesc.duration = duration;

        QList<QPushButton*> tagBtns = ui->tagContent->findChildren<QPushButton*>();
        for(auto& tagBtn : tagBtns){
            if(tagBtn->isChecked()){
                QString tagText = tagBtn->text();
                videoDesc.tags.append(tagText);
            }
        }

        if(videoDesc.tags.size() > 5){
            Toast::showMessage("最多只能选择5个标签");
            return;
        }

        // 给服务器发送上传视频信息请求
        auto dataCenter = model::DataCenter::getInstance();
        dataCenter->uploadVideoDescAsync(videoDesc);
    }
}

void UploadVideoPage::onLineEditTextChanged(const QString &text)
{
    QString leftWord = ui->leftWord->text();
    int linePos = leftWord.indexOf('/');
    // 最多的字符个数
    QString MaxCount = leftWord.mid(linePos + 1);
    // 输入的字符个数
    int currentCount = text.size();
    if(currentCount > MaxCount.toInt()) {
        ui->leftWord->setText(MaxCount + "/" + MaxCount);
    } else {
        ui->leftWord->setText(QString::number(currentCount) + "/" + MaxCount);
    }
}

void UploadVideoPage::onPlainEditTextChanged()
{
    QString text = ui->plainTextEdit->toPlainText();
    QString leftWord = ui->briefLeftWord->text();
    int linePos = leftWord.indexOf('/');
    // 最多的字符个数
    QString MaxCount = leftWord.mid(linePos + 1);
    // 输入的字符个数
    int currentCount = text.size();
    if(currentCount > MaxCount.toInt()) {
        ui->plainTextEdit->setPlainText(text.mid(0, MaxCount.toInt()));
        ui->briefLeftWord->setText(MaxCount + "/" + MaxCount);
        // 设置光标一直处于尾部状态
        // textCursor: 获取当前光标的位置
        // movePosition: 移动光标位置，QTextCursor::End移动到⽂本的末尾
        // QTextCursor::MoveAnchor表⽰移动光标时，光标的位置是固定的，
        // 不会创建⼀个选区（即不会选中⽂本）
        QTextCursor textCursor = ui->plainTextEdit->textCursor();
        textCursor.movePosition(QTextCursor::End, QTextCursor::MoveAnchor);
        ui->plainTextEdit->setTextCursor(textCursor);

    } else {
        ui->briefLeftWord->setText(QString::number(currentCount) + "/" + MaxCount);
    }
}

void UploadVideoPage::onChangeButtonClicked()
{
    QString coverImgPath = QFileDialog::getOpenFileName(nullptr, "选择视频封面", "", "*.png *.xpm *.jpg");
    if(coverImgPath.isEmpty()){
        LOG()<<"用户取消封面图的选择";
        return;
    }
    QPixmap pixmap(coverImgPath);
    pixmap = pixmap.scaled(ui->imageLabel->size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
    ui->imageLabel->setPixmap(pixmap);

    // ⽤⼾选择了图⽚，则不使⽤默认图⽚
    uploadPhoto(coverImgPath);
}

void UploadVideoPage::onUpdateTags(const QString &kind)
{
    addTagsByKind(kind);
}

void UploadVideoPage::addTagsByKind(const QString &kind)
{
    // 1.添加之前先清空之前的标签
    QList<QPushButton*> tagBtnList = ui->tagWidget->findChildren<QPushButton*>
                                      ();
    for(auto tagBtn : tagBtnList) {
        // 删除标签按钮，提交按钮不能删除--
        ui->tagLayout->removeWidget(tagBtn);
        delete tagBtn;
    }
    // 将添加的弹簧删除掉
    // 弹簧本来是最后⼀个控件，当layoyut中的按钮删除之后，弹簧就变成第0个控件了
    QLayoutItem* spacerItem = ui->tagLayout->itemAt(ui->tagLayout->count()-1);
    ui->tagLayout->removeItem(spacerItem);

    // 2. 根据kind获取标签--注意：如果key不存在直接返回
    if(kind.isEmpty()){
        return;
    }
    auto kindAndTagPtr = model::DataCenter::getInstance()->getKindAndTagClassPtr();
    auto kinds = model::DataCenter::getInstance()->getKindAndTagClassPtr()->getAllKind();
    auto tags = kindAndTagPtr->getTagsByKind(kind);
    // 3. 创建该标签对应的按钮
    for(auto& tag : tags.keys()){
        QPushButton* tagBtn = new QPushButton(ui->tagContent);
        tagBtn->setFixedSize(98, 49);
        tagBtn->setText(tag);
        tagBtn->setCheckable(true); // 设置按钮的状态为选中和未选中两种状态
        // QPushButton:checked 当按钮选中时

        // QPushButton:unchecked 当按钮未选中时
        tagBtn->setStyleSheet("QPushButton{"
                              "border : 1px solid #3ECEFE;"
                              "border-radius : 4px;"
                              "color : #3ECEFE;"
                              "font-family : 微软雅⿊;"
                              "font-size : 16px;"
                              "background-color : #FFFFFF;}"
                              "QPushButton:checked{"
                              "background-color : #3ECEFE;"
                              "color : #FFFFFF;}"
                              "QPushButton:unchecked{"
                              "background-color : #FFFFFF;"
                              "color : #3ECEFE;}");
        ui->tagLayout->addWidget(tagBtn);
    }
    // 在tagLayout最后放⼀个空⽩间距，将按钮挤到左侧
    ui->tagLayout->insertSpacing(tags.size(), ui->tagContent->width() -(98+20)*tags.size());
    ui->tagLayout->setSpacing(20);
}

void UploadVideoPage::onUploadVideoDone(const QString &videoId)
{
    ui->uploadProgress->setText("上传完成");
    ui->downIcon->show();
    this->videoFileId = videoId;
    this->isUploadVideoOK = true;

    // 设置视频首帧
    QString firstFrame = MpvPlayer::getVideoFirstFrame(videoPath);
    if(firstFrame.isEmpty()){
        LOG()<<"获取视频首帧失败";
        return;
    }

    // 将视频首帧作为视频封面图
    QPixmap pixmap(firstFrame);
    pixmap = pixmap.scaled(ui->imageLabel->size(), Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation);
    ui->imageLabel->setPixmap(pixmap);

    // 将封面图上传服务器
    this->uploadPhoto(firstFrame);
    QFile::remove(firstFrame);

    // // 获取视频总时长
    // // 不需要让视频渲染出来，即不需要传视频渲染窗口
    LOG()<<"获取视频总时长打印"<< videoPath;
    mpvPlayer = new MpvPlayer();
    mpvPlayer->startPlay(videoPath);
    mpvPlayer->pause();
    connect(mpvPlayer, &MpvPlayer::durationChanged, this, &UploadVideoPage::getDurationDone);
}

void UploadVideoPage::getDurationDone(int64_t duration)
{
    LOG()<<duration;
    this->duration = duration;
    isDurationOK = true;
    delete mpvPlayer;
    mpvPlayer = nullptr;
}

void UploadVideoPage::uploadPhoto(const QString &photoPath)
{
    // 读取图片数据，并将数据发送给服务器
    QByteArray imageData = loadFileToByteArray(photoPath);
    if(imageData.isEmpty()){
        LOG()<<"读取封面图失败!!!";
        return;
    }

    auto dataCenter = model::DataCenter::getInstance();
    dataCenter->uploadPhotoAsync(imageData, ui->imageLabel);
}

void UploadVideoPage::resetPage()
{
    ui->fileName->setText("【这里是文件名】直接取源文件名称即可");
    ui->uploadProgress->setText("上传中...");
    ui->downIcon->hide();

    ui->videoTitle->setText("");
    ui->plainTextEdit->setPlainText("");
    ui->imageLabel->setStyleSheet("#imageLabel{border-image : url(:/images/uploadVideoPage/fenmian.png);}");

    // 分类和标签恢复到默认值
    ui->kinds->setCurrentIndex(-1);
    addTagsByKind("");

    videoPath = "";
    isUploadVideoOK = false;
    isUploadPhotoOK = false;
    isDurationOK = false;
    videoFileId = "";
    coverImageId = "";
    duration = 0;
}
